package ware.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.feign.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import ware.constant.WareConstant;
import ware.domain.Purchase;
import ware.domain.PurchaseDetail;
import ware.service.PurchaseDetailService;
import ware.service.PurchaseService;
import ware.mapper.PurchaseMapper;
import org.springframework.stereotype.Service;
import ware.service.WareSkuService;
import ware.vo.FinishVo;
import ware.vo.ItemVo;
import ware.vo.MergeVo;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author panghu
 * @description 针对表【wms_purchase(采购信息)】的数据库操作Service实现
 * @createDate 2023-03-04 21:05:07
 */
@Service
public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, Purchase>
        implements PurchaseService {

    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private WareSkuService wareSkuService;

    @Override
    public Page<Purchase> querPage(Map<String, Object> params) {
        LambdaQueryWrapper<Purchase> queryWrapper = getQueryWrapper(params);
        Page<Purchase> wareInfoPage = new Page<>(Integer.parseInt((String) params.get("page")), Integer.parseInt((String) params.get("limit")));
        return this.baseMapper.selectPage(wareInfoPage, queryWrapper);
    }

    @Override
    @Transactional
    public void mergePurchase(MergeVo mergeVo) {
        Long purchaseId = mergeVo.getPurchaseId();
        if (ObjectUtils.isEmpty(purchaseId)) {
            // 新建采购单
            Purchase purchase = new Purchase();
            purchase.setStatus(WareConstant.PURCHASE_CREATE);
            purchase.setCreateTime(new Date());
            purchase.setUpdateTime(new Date());
            this.save(purchase);
            purchaseId = purchase.getId();
        }

        List<Long> items = mergeVo.getItems();
        //  确认采购单状态正确(有问题)
        mergeVo.getItems().forEach(item -> {
            PurchaseDetail id = purchaseDetailService.getById(item);
            if (!id.getStatus().equals(WareConstant.PURCHASE_CREATE) && !id.getStatus().equals(WareConstant.PURCHASE_ASSIGNED)) {
                throw new RuntimeException("采购单状态不正确，不可以合并哦");
            }
        });
        Long finalPurchaseId = purchaseId;
        // 更改采购项
        List<PurchaseDetail> purchaseDetailList = items.stream().map(item -> {
            PurchaseDetail purchaseDetail = new PurchaseDetail();
            purchaseDetail.setId(item);
            purchaseDetail.setPurchaseId(finalPurchaseId);
            purchaseDetail.setStatus(WareConstant.PURCHASE_ASSIGNED);
            return purchaseDetail;
        }).collect(Collectors.toList());
        purchaseDetailService.updateBatchById(purchaseDetailList);
        // 更改采购单
        Purchase purchase = new Purchase();
        purchase.setId(finalPurchaseId);
        purchase.setUpdateTime(new Date());
        this.updateById(purchase);
    }

    @Override
    @Transactional
    public void received(List<Long> ids) {
        // 确认当前采购单是新建或者已分配状态
        List<Purchase> purchaseList = ids.stream().map(this::getById)
                .filter(item -> Objects.equals(item.getStatus(), WareConstant.PURCHASE_CREATE)
                        || item.getStatus().equals(WareConstant.PURCHASE_ASSIGNED))
                .peek(item -> {
                    // 更改采购单的状态
                    item.setStatus(WareConstant.PURCHASE_RECEIVE);
                    item.setUpdateTime(new Date());
                })
                .collect(Collectors.toList());
        this.updateBatchById(purchaseList);
        // 更改采购项的状态
        purchaseList.forEach(item -> {
            List<PurchaseDetail> purchaseDetailList = purchaseDetailService.listDetailByPurchaseId(item.getId());
            List<PurchaseDetail> detailList = purchaseDetailList.stream().map(purchaseDetail -> {
                PurchaseDetail detail = new PurchaseDetail();
                detail.setId(purchaseDetail.getId());
                detail.setStatus(WareConstant.PURCHASE_RECEIVE);
                return detail;
            }).collect(Collectors.toList());
            purchaseDetailService.updateBatchById(detailList);
        });

    }

    @Override
    @Transactional
    public R purchaseFinish(FinishVo finishVos) {
        Long purchaseId = finishVos.getId();
        List<ItemVo> items = finishVos.getItems();
        boolean flag = true;
        List<PurchaseDetail> purchaseDetailList = new ArrayList<>();
        for (ItemVo item : items) {
            PurchaseDetail purchaseDetail = new PurchaseDetail();
            if (item.getStatus().equals(WareConstant.PURCHASE_ERROR)) {
                flag = false;
            } else {
                // 采购成功，进行入库
                PurchaseDetail detail = purchaseDetailService.getById(item.getItemId());
                wareSkuService.addStock(detail.getSkuId(), detail.getWareId(), detail.getSkuNum());
            }
            purchaseDetail.setId(item.getItemId());
            purchaseDetail.setStatus(item.getStatus());
            purchaseDetailList.add(purchaseDetail);
        }
        // 改变采购项的状态
        purchaseDetailService.updateBatchById(purchaseDetailList);
        // 改变采购单状态
        // todo 采购单的状态没有改变
        Purchase purchase = new Purchase();
        if (flag) {
            purchase.setStatus(WareConstant.PURCHASE_FINISH);
        } else {
            purchase.setStatus(WareConstant.PURCHASE_ERROR);
        }
        purchase.setId(purchaseId);
        purchase.setUpdateTime(new Date());
        this.updateById(purchase);
        return R.ok();
    }

    private LambdaQueryWrapper<Purchase> getQueryWrapper(Map<String, Object> params) {
        LambdaQueryWrapper<Purchase> wrapper = new LambdaQueryWrapper<>();
        if (!ObjectUtils.isEmpty(params.get("key"))) {
            Object key = params.get("key");
            wrapper.like(Purchase::getPhone, key)
                    .or().eq(Purchase::getId, key)
                    .or().like(Purchase::getStatus, key)
                    .or().eq(Purchase::getAmount, key)
            ;
        }
        wrapper.eq(!ObjectUtils.isEmpty(params.get("unreceived")), Purchase::getStatus, 0)
                .or()
                .eq(!ObjectUtils.isEmpty(params.get("unreceived")), Purchase::getStatus, 1)
        ;
        return wrapper;
    }
}




